package com.chenjun.designpattern.behavior.template;

/**
 * <p>
 * 模板模式（Template ）：
 * 
 * <p>
 * 模板方法模式是类的行为模式。准备一个抽象类，将部分逻辑以具体方法以及具体构造函数的形式实现，
 * 然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法，从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
 * 
 * <p>
 * 模式中的角色
 * 
 * <p>
 * 抽象类（AbstractClass）：实现了模板方法，定义了算法的骨架。
 * <p>
 * 具体类（ConcreteClass)：实现抽象类中的抽象方法，已完成完整的算法。
 * <p>
 * 在C++的STL类库和JAVA类集框架中大量使用了这种设计模式
 * 
 * 模板方法： 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中，模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
 * @author Administrator
 */
public class 模板模式
{
	public static void main(String[] args)
	{
		Book book = new Book();
		book.setBookName("Thinking in Java");
		book.setPages(880);
		book.setPrice(68);
		book.setAuthor("Bruce Eckel");
		book.setIsbn("9787111213826");
		XMLFormatter xmlFormatter = new XMLFormatter();
		String result = xmlFormatter.formatBook(book);
		System.out.println(result);
		JSONFormatter jsonFormatter = new JSONFormatter();
		result = jsonFormatter.formatBook(book);
		System.out.println(result);
	}
}

/**
 * 抽象格式化类,内含abstract String formating 抽象方法
 * @author Administrator
 *
 */
abstract class Formatter
{
	public String formatBook(Book book)
	{
		beforeFormat();
		String result = formating(book);
		afterFormat();
		return result;
	}

	protected void beforeFormat()
	{
		System.out.println("format begins");
	}

	protected abstract String formating(Book book);

	protected void afterFormat()
	{
		System.out.println("format finished");
	}
}

/**
 * 然后要定义专门的子类来处理每种传输格式的具体逻辑， 这样不同传输格式的逻辑可以从一个方法里分离开，明显便于阅读和理解。
 * 定义类XMLFormatter继承自Formatter，里面加入处理XML格式的具体逻辑：
 * 
 * @author Administrator
 *
 */
class XMLFormatter extends Formatter
{
	@Override
	protected String formating(Book book)
	{
		String result = "";
		result += "<book_name>" + book.getBookName() + "</book_name>\n";
		result += "<pages>" + book.getPages() + "</pages>\n";
		result += "<price>" + book.getPrice() + "</price>\n";
		result += "<author>" + book.getAuthor() + "</author>\n";
		result += "<isbn>" + book.getIsbn() + "</isbn>\n";
		return result;
	}
}

/**
 * 定义类JSONFormatter继承自Formatter，里面加入处理JSON格式的具体逻辑：
 */
class JSONFormatter extends Formatter
{
	@Override
	protected String formating(Book book)
	{
		String result = "";
		result += "{\n";
		result += "\"book_name\" : \"" + book.getBookName() + "\",\n";
		result += "\"pages\" : \"" + book.getPages() + "\",\n";
		result += "\"price\" : \"" + book.getPrice() + "\",\n";
		result += "\"author\" : \"" + book.getAuthor() + "\",\n";
		result += "\"isbn\" : \"" + book.getIsbn() + "\",\n";
		result += "}";
		return result;
	}
}

/**
 * 书籍类
 * 
 * @author Administrator
 */
class Book
{
	private String bookName;

	private int pages;

	private double price;

	private String author;

	private String isbn;

	public String getBookName()
	{
		return bookName;
	}

	public void setBookName(String bookName)
	{
		this.bookName = bookName;
	}

	public int getPages()
	{
		return pages;
	}

	public void setPages(int pages)
	{
		this.pages = pages;
	}

	public double getPrice()
	{
		return price;
	}

	public void setPrice(double price)
	{
		this.price = price;
	}

	public String getAuthor()
	{
		return author;
	}

	public void setAuthor(String author)
	{
		this.author = author;
	}

	public String getIsbn()
	{
		return isbn;
	}

	public void setIsbn(String isbn)
	{
		this.isbn = isbn;
	}
}
